home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / grafik / 3d & render tools / irit / contrib / mssketch / mssketch.c < prev   
Encoding:
C/C++ Source or Header  |  1996-07-16  |  47.3 KB  |  1,436 lines

  1. /*****************************************************************************
  2. *   An X11 driver using only libx11.a.                         *
  3. *                                         *
  4. * Written by:  Gershon Elber                Ver 0.1, June 1993.  *
  5. *****************************************************************************/
  6.  
  7. #ifdef __hpux
  8. typedef char *caddr_t;           /* Awful kludge. Let me know of a better way. */
  9. #endif /* __hpux */
  10.  
  11. #include <X11/Xlib.h>
  12. #include <X11/Xutil.h>
  13. #include <X11/cursorfont.h>
  14. #include <X11/Xresource.h>
  15.  
  16. #include <Xm/MainW.h>
  17. #include <Xm/PushB.h>
  18. #include <Xm/ToggleB.h>
  19. #include <Xm/RowColumn.h>
  20. #include <Xm/Label.h>
  21. #include <Xm/Scale.h>
  22. #include <Xm/Form.h>            
  23.  
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <math.h>
  27. #include <ctype.h>
  28.  
  29. #include "irit_sm.h"
  30. #include "genmat.h"
  31. #include "iritprsr.h"
  32. #include "allocate.h"
  33. #include "attribut.h"
  34. #include "ip_cnvrt.h"
  35. #include "cagd_lib.h"
  36. #include "symb_lib.h"
  37. #include "iritgrap.h"
  38. #include "irit_soc.h"
  39.  
  40. #define X11_FONT_NAME        "8x13"
  41.  
  42. #define RESOURCE_NAME        "irit"
  43.  
  44. #define DEFAULT_TRANS_WIDTH    200
  45. #define DEFAULT_TRANS_HEIGHT    500
  46. #define DEFAULT_VIEW_WIDTH    400
  47. #define DEFAULT_VIEW_HEIGHT    400
  48.  
  49. #define X11_MAP_X_COORD(x) (((int) ((x + 1.0) * ViewWidth)) / 2)
  50. #define X11_MAP_Y_COORD(y) (((int) ((1.0 - y) * ViewHeight)) / 2)
  51.  
  52. #define X11_INVMAP_X_COORD(x) (((RealType) 2 * x) / ViewWidth - 1.0)
  53. #define X11_INVMAP_Y_COORD(y) (1.0 - ((RealType) 2 * y) / ViewHeight)
  54.  
  55. /* X global specific staff goes here: */
  56. static Display *XDisplay;
  57. static int XScreen;
  58. static Window XRoot;
  59. static Colormap XColorMap;
  60. static GC XTransGraphContext;
  61. static GC XViewGraphContext;
  62. static Visual *XVisual;
  63. static XImage *XImageBuffer;
  64. static Pixmap XIcon;
  65. static Cursor XCursor;
  66. static XColor BlackColor;
  67. static XFontStruct *XLoadedFont;
  68. static XGCValues CrntColorHighIntensity, CrntColorLowIntensity;
  69. static XColor
  70.     *TransCursorColor = NULL,
  71.     *ViewCursorColor = NULL;
  72. static unsigned long
  73.     TransBackGroundPixel,
  74.     TransBorderPixel,
  75.     TransTextPixel,
  76.     TransSubWinBackPixel,
  77.     TransSubWinBorderPixel,
  78.     ViewBackGroundPixel,
  79.     ViewBorderPixel,
  80.     ViewTextPixel;
  81. static int
  82.     XFontYOffsetToCenter = 0,
  83.     TransHasSize = FALSE,
  84.     TransHasPos = FALSE,
  85.     TransPosX = 0,
  86.     TransPosY = 0,
  87.     ViewHasSize = FALSE,
  88.     ViewHasPos = FALSE,
  89.     ViewPosX = 0,
  90.     ViewPosY = 0,
  91.     CurrentXPosition = 0,
  92.     CurrentYPosition = 0;
  93. static unsigned int
  94.     TransBorderWidth = 1,
  95.     TransSubWinBorderWidth = 1,
  96.     TransWidth = DEFAULT_TRANS_WIDTH,
  97.     TransHeight = DEFAULT_TRANS_HEIGHT,
  98.     ViewBorderWidth = 1,
  99.     ViewWidth = DEFAULT_VIEW_WIDTH,
  100.     ViewHeight = DEFAULT_VIEW_HEIGHT,
  101.     MaxColors = IG_MAX_COLOR;
  102.  
  103. /* X Colors to be used for viewed object (see also iritgrap.h): */
  104. static int XViewColorDefs[IG_MAX_COLOR + 1][3] =
  105. {
  106.     {     0,     0,     0 },  /* 0. IG_IRIT_BLACK */
  107.     {     0,     0, 43350 },  /* 1. IG_IRIT_BLUE */
  108.     {     0, 43350,     0 },  /* 2. IG_IRIT_GREEN */
  109.     {     0, 43350, 43350 },  /* 3. IG_IRIT_CYAN */
  110.     { 43350,     0,     0 },  /* 4. IG_IRIT_RED */
  111.     { 43350,     0, 43350 },  /* 5. IG_IRIT_MAGENTA */
  112.     { 43350, 43350,     0 },  /* 6. IG_IRIT_BROWN */
  113.     { 43350, 43350, 43350 },  /* 7. IG_IRIT_LIGHTGREY */
  114.     { 21675, 21675, 21675 },  /* 8. IG_IRIT_DARKGRAY */
  115.     { 21675, 21675, 65535 },  /* 9. IG_IRIT_LIGHTBLUE */
  116.     { 21675, 65535, 21675 },  /* 10. IG_IRIT_LIGHTGREEN */
  117.     { 21675, 65535, 65535 },  /* 11. IG_IRIT_LIGHTCYAN */
  118.     { 65535, 21675, 21675 },  /* 12. IG_IRIT_LIGHTRED */
  119.     { 65535, 21675, 65535 },  /* 13. IG_IRIT_LIGHTMAGENTA */
  120.     { 65535, 65535, 21675 },  /* 14. IG_IRIT_YELLOW */
  121.     { 65535, 65535, 65535 }   /* 15. IG_IRIT_WHITE */
  122. };
  123. XColor XViewColorsHigh[IG_MAX_COLOR + 1];
  124. XColor XViewColorsLow[IG_MAX_COLOR + 1];
  125.  
  126. /* X Viewing window staff goes here: */
  127. static Window ViewWndw;
  128.  
  129. /* X transformation window staff goes here: */
  130. static Window TransformWndw;
  131. static Window ObjScrTglWndw;
  132. static Window PersOrthoTglWndw, PersOrthoZWndw;
  133. static Window RotateXWndw, RotateYWndw, RotateZWndw;
  134. static Window TranslateXWndw, TranslateYWndw, TranslateZWndw;
  135. static Window ScaleWndw;
  136. static Window DepthCueWndw;
  137. static Window SaveMatrixWndw;
  138. static Window PushMatrixWndw;
  139. static Window PopMatrixWndw;
  140. static Window QuitWndw;
  141.  
  142. /* Motif staff. */
  143. static Widget TopLevel, MainForm;
  144. static RealType OldValue;
  145.  
  146. /* Viewing state variables: */
  147. static int
  148.     SubWindowWidthState2 = 1,
  149.     SubWindowHeightState2 = 1;
  150.  
  151. static void SetColorIndex(int c);
  152. static void SetColorRGB(int Color[3]);
  153. static char *ReadOneXDefault(char *Entry);
  154. static void ReadXDefaults(void);
  155. static void SetTransformWindow(int argc, char **argv);
  156. static void RedrawTransformWindow(void);
  157. static Window SetTransformSubWindow(int SubTransPosX, int SubTransPosY,
  158.             unsigned int SubTransWidth, unsigned int SubTransHeight);
  159. static void RedrawTransformSubWindow(Window Win,
  160.     int SubTransPosX, int SubTransPosY,
  161.     unsigned int SubTransWidth, unsigned int SubTransHeight,
  162.     int DrawMiddleVertLine, char *DrawString);
  163. static void SetViewWindow(int argc, char **argv);
  164. static void GraphicFlush(void);
  165. static IGGraphicEventType GetGraphicEvent(XtAppContext App,
  166.                       RealType *ChangeFactor);
  167. static void DrawText(Window Win, char *Str, int PosX, int PosY,
  168.              unsigned long Color);
  169.  
  170. static void CreateControlPanel(Widget TopLevel);
  171. static void ScalesCB(Widget w, IGGraphicEventType EventType);
  172. static void DragCB(Widget w, IGGraphicEventType EventType);
  173. static void TransformCB(Widget w, int State);
  174.  
  175. /****************************************************************************
  176. * Pop up all windows, read input and display.                    *
  177. ****************************************************************************/
  178. void main(int argc, char **argv)
  179. {
  180.     int i;
  181.     XGCValues values;
  182.     XtAppContext App;
  183.     RealType ChangeFactor[2];
  184.     IGGraphicEventType Event;
  185.     IPObjectStruct *PObjects;
  186.  
  187.     IGConfigureGlobals("x11drvs", argc, argv);
  188.  
  189.     /* Lets see if we can get access to the X server before we even start: */
  190.     if ((XDisplay = (Display *) XOpenDisplay(NULL)) == NULL) {
  191.     fprintf(stderr, "x11drvs: Failed to access X server, abored.\n");
  192.         exit(-1);
  193.     }
  194.     if ((XLoadedFont = XLoadQueryFont(XDisplay, X11_FONT_NAME)) == NULL) {
  195.     fprintf(stderr,
  196.         "x11drvs: Failed to load required X font \"%s\", aborted.\n",
  197.         X11_FONT_NAME);
  198.     exit(-1);
  199.     }
  200.     XFontYOffsetToCenter = (XLoadedFont -> ascent - XLoadedFont -> descent + 1)
  201.                                     / 2;
  202.  
  203.     XScreen = DefaultScreen(XDisplay);
  204.     XRoot = RootWindow(XDisplay, XScreen);
  205.     XColorMap = DefaultColormap(XDisplay, XScreen);
  206.     XVisual = DefaultVisual(XDisplay, XScreen);
  207.     values.foreground = WhitePixel(XDisplay, XScreen);
  208.     values.background = BlackPixel(XDisplay, XScreen);
  209.     values.font = XLoadedFont -> fid;
  210.     XTransGraphContext = XCreateGC(XDisplay, XRoot,
  211.                   GCForeground | GCBackground | GCFont, &values);
  212.     XViewGraphContext = XCreateGC(XDisplay, XRoot,
  213.                   GCForeground | GCBackground, &values);
  214.     
  215.     if (XrmGetDatabase(XDisplay) == NULL)
  216.     XGetDefault(XDisplay, "", "");
  217.     ReadXDefaults();
  218.  
  219.     for (i = 0; i <= IG_MAX_COLOR; i++) {
  220.     XViewColorsHigh[i].red   = XViewColorDefs[i][0];
  221.     XViewColorsHigh[i].green = XViewColorDefs[i][1];
  222.     XViewColorsHigh[i].blue  = XViewColorDefs[i][2];
  223.  
  224.     /* If fails to allocate the color - take WHITE instead. */
  225.     if (!XAllocColor(XDisplay, XColorMap, &XViewColorsHigh[i]))
  226.         XViewColorsHigh[i].pixel = WhitePixel(XDisplay, XScreen);
  227.  
  228.     XViewColorsLow[i].red   = XViewColorDefs[i][0] / 2;
  229.     XViewColorsLow[i].green = XViewColorDefs[i][1] / 2;
  230.     XViewColorsLow[i].blue  = XViewColorDefs[i][2] / 2;
  231.  
  232.     /* If fails to allocate the color - take WHITE instead. */
  233.     if (!XAllocColor(XDisplay, XColorMap, &XViewColorsLow[i]))
  234.         XViewColorsLow[i].pixel = WhitePixel(XDisplay, XScreen);
  235.     }
  236.  
  237.     IGCreateStateMenu();
  238.  
  239.     TopLevel = XtVaAppInitialize(&App, "Control",
  240.                  NULL, 0, &argc, argv, NULL, NULL);
  241.     if (TransHasSize)
  242.     XtVaSetValues(TopLevel,
  243.               XmNheight, TransHeight,
  244.               NULL);
  245.     if (TransHasPos)
  246.     XtVaSetValues(TopLevel,
  247.               XmNx, TransPosX + TransWidth,
  248.               XmNy, TransPosY,
  249.               NULL);
  250.     CreateControlPanel(TopLevel);
  251.     XtRealizeWidget(TopLevel);
  252.  
  253.     SetTransformWindow(argc, argv);
  254.     SetViewWindow(argc, argv);
  255.  
  256.     while ((Event = GetGraphicEvent(App, ChangeFactor)) != IG_EVENT_QUIT) {
  257.     ChangeFactor[0] *= IGGlblChangeFactor;
  258.     ChangeFactor[1] *= IGGlblChangeFactor;
  259.  
  260.     if (IGProcessEvent(Event, ChangeFactor))
  261.         IGRedrawViewWindow();
  262.     }
  263.  
  264.     XFreeGC(XDisplay, XViewGraphContext);
  265.     XFreeGC(XDisplay, XTransGraphContext);
  266.     XUnloadFont(XDisplay, XLoadedFont -> fid);
  267.     XCloseDisplay(XDisplay);
  268. }
  269.  
  270. /*****************************************************************************
  271. * Construct global pop up menu.                             *
  272. *****************************************************************************/
  273. void IGCreateStateMenu(void)
  274. {
  275. }
  276.  
  277. /****************************************************************************
  278. * Create Motif Based Control Panel                *
  279. ****************************************************************************/
  280. static void CreateControlPanel(Widget TopLevel)
  281. {
  282.     Widget MainWndw, Slider, QuitButton, Scale, Label1, Label2;
  283.     IGGraphicEventType EventType;
  284.  
  285.     MainWndw = XtVaCreateManagedWidget("Main Window",
  286.                        xmMainWindowWidgetClass,    TopLevel, NULL);
  287.     MainForm = XtVaCreateManagedWidget("Mainform",
  288.                        xmFormWidgetClass,      MainWndw,
  289.                        XmNtopAttachment,       XmATTACH_WIDGET,
  290.                        XmNtopWidget,            MainWndw,
  291.                        XmNbottomAttachment,    XmATTACH_WIDGET,
  292.                        XmNbottomWidget,        MainWndw,  
  293.                        XmNleftAttachment,      XmATTACH_WIDGET,
  294.                        XmNleftWidget,            MainWndw,
  295.                        XmNrightAttachment,     XmATTACH_WIDGET,
  296.                        XmNrightWidget,            MainWndw,
  297.                        XmNfractionBase,        15,
  298.                        NULL);    
  299.  
  300.     Slider = XtVaCreateManagedWidget("Slider",
  301.                      xmFormWidgetClass,    MainForm,
  302.                      XmNtopAttachment,     XmATTACH_FORM,
  303.                      XmNbottomAttachment,  XmATTACH_POSITION,
  304.                      XmNbottomPosition,    14,
  305.                      NULL);
  306.     Label1 = XtVaCreateManagedWidget("Locality",
  307.                      xmLabelWidgetClass, Slider,
  308.                      XmNtopAttachment,   XmATTACH_FORM,
  309.                      NULL);
  310.     Label2 = XtVaCreateManagedWidget("Globality",
  311.                      xmLabelWidgetClass,  Slider,
  312.                      XmNbottomAttachment, XmATTACH_FORM,
  313.                      NULL);
  314.     Scale = XtVaCreateManagedWidget("SliderScale",
  315.                     xmScaleWidgetClass,   Slider,
  316.                     XmNorientation,      XmVERTICAL,
  317.                     XmNtopAttachment,     XmATTACH_WIDGET,
  318.                     XmNtopWidget,         Label1,
  319.                     XmNbottomAttachment,  XmATTACH_WIDGET,
  320.                     XmNbottomWidget,      Label2,
  321.                     XmNminimum,           0,
  322.                     XmNmaximum,          1000,
  323.                     XmNshowValue,      True,
  324.                     XmNdecimalPoints,      2,
  325.                     NULL);    
  326.     XtAddCallback(Scale, XmNvalueChangedCallback,
  327.           (XtCallbackProc) ScalesCB, (XtPointer) EventType);
  328.     XtAddCallback(Scale, XmNdragCallback, (XtCallbackProc) DragCB,
  329.           (XtPointer) EventType);
  330.  
  331.     QuitButton = XtVaCreateManagedWidget("QuitBtn",
  332.                      xmFormWidgetClass,   MainForm,
  333.                      XmNbottomAttachment, XmATTACH_FORM,
  334.                      XmNtopAttachment,    XmATTACH_WIDGET,
  335.                      XmNtopWidget,          Slider,
  336.                      XmNleftAttachment,   XmATTACH_FORM,
  337.                      XmNrightAttachment,  XmATTACH_FORM,
  338.                      NULL);
  339.     QuitButton = XtVaCreateManagedWidget("QUIT",
  340.                      xmPushButtonWidgetClass, QuitButton, 
  341.                      XmNleftAttachment,    XmATTACH_FORM,
  342.                      XmNrightAttachment,   XmATTACH_FORM,
  343.                      XmNbottomAttachment,  XmATTACH_FORM,
  344.                      XmNtopAttachment,     XmATTACH_FORM,
  345.                      NULL);
  346.  
  347.     XtAddCallback(QuitButton, XmNactivateCallback,
  348.           (XtCallbackProc) TransformCB, (XtPointer) IG_EVENT_QUIT);
  349. }
  350.  
  351. /****************************************************************************
  352. * Routine to move in 2D normalized (-1..1) view space.                *
  353. ****************************************************************************/
  354. void IGMoveTo2D(RealType X, RealType Y)
  355. {
  356.     CurrentXPosition = X11_MAP_X_COORD(X);
  357.     CurrentYPosition = X11_MAP_Y_COORD(Y);
  358. }
  359.  
  360. /****************************************************************************
  361. * Routine to draw in 2D normalized (-1..1) view space.                *
  362. ****************************************************************************/
  363. void IGLineTo2D(RealType X, RealType Y)
  364. {
  365.     int NewX, NewY;
  366.  
  367.     XDrawLine(XDisplay, ViewWndw, XViewGraphContext,
  368.           CurrentXPosition,
  369.           CurrentYPosition,
  370.           NewX = X11_MAP_X_COORD(X),
  371.           NewY = X11_MAP_Y_COORD(Y));
  372.  
  373.     CurrentXPosition = NewX;
  374.     CurrentYPosition = NewY;
  375. }
  376.  
  377. /****************************************************************************
  378. * Routine to set the intensity of a color (high or low).            *
  379. ****************************************************************************/
  380. void IGSetColorIntensity(int High)
  381. {
  382.     XChangeGC(XDisplay, XViewGraphContext, GCForeground,
  383.           High ? &CrntColorHighIntensity : &CrntColorLowIntensity);
  384.     IGGlblIntensityHighState = High;
  385. }
  386.  
  387. /****************************************************************************
  388. * Routine to set the color according to the given object's color.        *
  389. ****************************************************************************/
  390. void IGSetColorObj(IPObjectStruct *PObj)
  391. {
  392.     int c, Color[3];
  393.  
  394.     if (AttrGetObjectRGBColor(PObj, &Color[0], &Color[1], &Color[2])) {
  395.     SetColorRGB(Color);
  396.     }
  397.     else if ((c = AttrGetObjectColor(PObj)) != IP_ATTR_NO_COLOR) {
  398.     SetColorIndex(c);
  399.     }
  400.     else {
  401.     /* Use white as default color: */
  402.     SetColorIndex(IG_IRIT_WHITE);
  403.     }
  404. }
  405.  
  406. /****************************************************************************
  407. * Routine to set the line width to draw the given object, in pixels.        *
  408. ****************************************************************************/
  409. void IGSetWidthObj(int Width)
  410. {
  411. }
  412.  
  413. /****************************************************************************
  414. * Routine to set the color according to the given color index.            *
  415. ****************************************************************************/
  416. static void SetColorIndex(int color)
  417. {
  418.     if (color >= MaxColors)
  419.     color = IG_IRIT_WHITE;
  420.  
  421.     CrntColorHighIntensity.foreground = XViewColorsHigh[color].pixel;
  422.     CrntColorLowIntensity.foreground = XViewColorsLow[color].pixel;
  423.     XChangeGC(XDisplay, XViewGraphContext, GCForeground,
  424.           &CrntColorHighIntensity);
  425.     IGGlblIntensityHighState = TRUE;
  426. }
  427.  
  428. /****************************************************************************
  429. * Routine to set the color according to the given RGB values.            *
  430. ****************************************************************************/
  431. static void SetColorRGB(int Color[3])
  432. {
  433.     XColor XClr;
  434.     XGCValues values;
  435.  
  436.     XClr.red   = (Color[0] << 8);
  437.     XClr.green = (Color[1] << 8);
  438.     XClr.blue  = (Color[2] << 8);
  439.  
  440.     /* If fails to allocate the color - take WHITE instead. */
  441.     if (!XAllocColor(XDisplay, XColorMap, &XClr)) {
  442.     fprintf(stderr,
  443.         "x11drvs: Failed to allocate color, selected WHITE instead\n");
  444.     XClr.pixel = WhitePixel(XDisplay, XScreen);
  445.     }
  446.     CrntColorHighIntensity.foreground = XClr.pixel;
  447.  
  448.     XClr.red   = (Color[0] << 7);
  449.     XClr.green = (Color[1] << 7);
  450.     XClr.blue  = (Color[2] << 7);
  451.  
  452.     /* If fails to allocate the color - take WHITE instead. */
  453.     if (!XAllocColor(XDisplay, XColorMap, &XClr)) {
  454.     fprintf(stderr,
  455.         "x11drvs: Failed to allocate color, selected WHITE instead\n");
  456.     XClr.pixel = WhitePixel(XDisplay, XScreen);
  457.     }
  458.     CrntColorLowIntensity.foreground = XClr.pixel;
  459.  
  460.     XChangeGC(XDisplay, XViewGraphContext, GCForeground,
  461.           &CrntColorHighIntensity);
  462.     IGGlblIntensityHighState = TRUE;
  463. }
  464.  
  465. /*****************************************************************************
  466. * Read one default from X resource data base.                     *
  467. *****************************************************************************/
  468. static char *ReadOneXDefault(char *Entry)
  469. {
  470.     XrmString Type;
  471.     XrmValue Result;
  472.     char Line[LINE_LEN_LONG];
  473.  
  474.     sprintf(Line, "%s.%s", RESOURCE_NAME, Entry);
  475.     if (XrmGetResource(XrmGetDatabase(XDisplay), Line,
  476.                "Program.Name", &Type, &Result ) )
  477.     return Result.addr;
  478.     else
  479.     return NULL;
  480. }
  481.  
  482. /*****************************************************************************
  483. * Read Defaults from X data base.                         *
  484. *****************************************************************************/
  485. static void ReadXDefaults(void)
  486. {
  487.     int i;
  488.     XColor Color;
  489.     char *TransBackGroundColor = ReadOneXDefault("Trans.BackGround"),
  490.          *TransBorderColor = ReadOneXDefault("Trans*BorderColor"),
  491.          *TransBorderWidthStr = ReadOneXDefault("Trans*BorderWidth"),
  492.          *TransTextColor = ReadOneXDefault("Trans.TextColor"),
  493.          *TransSubWinBackColor = ReadOneXDefault("Trans.SubWin.BackGround"),
  494.          *TransSubWinBorderColor = ReadOneXDefault("Trans.SubWin.BorderColor"),
  495.          *TransSubWinBorderWidthStr = ReadOneXDefault("Trans.SubWin.BorderWidth"),
  496.          *TransGeometry = ReadOneXDefault("Trans.Geometry"),
  497.          *TransCursorColorStr = ReadOneXDefault("Trans.CursorColor"),
  498.          *ViewBackGroundColor = ReadOneXDefault("View.BackGround"),
  499.          *ViewTextColor = ReadOneXDefault("View.TextColor"),
  500.          *ViewBorderColor = ReadOneXDefault("View.BorderColor"),
  501.          *ViewBorderWidthStr = ReadOneXDefault("View.BorderWidth"),
  502.          *ViewGeometry = ReadOneXDefault("View.Geometry"),
  503.          *ViewCursorColorStr = ReadOneXDefault("View.CursorColor"),
  504.          *MaxColorsStr = ReadOneXDefault("MaxColors");
  505.  
  506.     if (XParseColor(XDisplay, XColorMap, "Black", &BlackColor))
  507.     XAllocColor(XDisplay, XColorMap, &BlackColor);
  508.  
  509.     if (TransBackGroundColor != NULL &&
  510.     XParseColor(XDisplay, XColorMap, TransBackGroundColor, &Color) &&
  511.     XAllocColor(XDisplay, XColorMap, &Color))
  512.     TransBackGroundPixel = Color.pixel;
  513.     else
  514.     TransBackGroundPixel = BlackPixel(XDisplay, XScreen);
  515.  
  516.     if (TransBorderColor != NULL &&
  517.     XParseColor(XDisplay, XColorMap, TransBorderColor, &Color) &&
  518.     XAllocColor(XDisplay, XColorMap, &Color))
  519.     TransBorderPixel = Color.pixel;
  520.     else
  521.     TransBorderPixel = WhitePixel(XDisplay, XScreen);
  522.  
  523.     if (TransBorderWidthStr)
  524.     TransBorderWidth = atoi(TransBorderWidthStr);
  525.     else
  526.     TransBorderWidth = 1;
  527.  
  528.     if (TransTextColor != NULL &&
  529.     XParseColor(XDisplay, XColorMap, TransTextColor, &Color) &&
  530.     XAllocColor(XDisplay, XColorMap, &Color))
  531.     TransTextPixel = Color.pixel;
  532.     else
  533.     TransTextPixel = WhitePixel(XDisplay, XScreen);
  534.  
  535.     if (TransSubWinBackColor != NULL &&
  536.     XParseColor(XDisplay, XColorMap, TransSubWinBackColor, &Color) &&
  537.     XAllocColor(XDisplay, XColorMap, &Color))
  538.     TransSubWinBackPixel = Color.pixel;
  539.     else
  540.     TransSubWinBackPixel = BlackPixel(XDisplay, XScreen);
  541.  
  542.     if (TransSubWinBorderColor != NULL &&
  543.     XParseColor(XDisplay, XColorMap, TransSubWinBorderColor, &Color) &&
  544.     XAllocColor(XDisplay, XColorMap, &Color))
  545.     TransSubWinBorderPixel = Color.pixel;
  546.     else
  547.     TransSubWinBorderPixel = WhitePixel(XDisplay, XScreen);
  548.  
  549.     if (TransSubWinBorderWidthStr)
  550.     TransSubWinBorderWidth = atoi(TransSubWinBorderWidthStr);
  551.     else
  552.     TransSubWinBorderWidth = 1;
  553.  
  554.     if (IGGlblTransPrefPos &&
  555.     sscanf(IGGlblTransPrefPos, "%d,%d,%d,%d",
  556.            &TransPosX, &TransWidth, &TransPosY, &TransHeight) == 4) {
  557.     TransWidth -= TransPosX;
  558.     TransHeight -= TransPosY;
  559.     TransHasSize = TransHasPos = TRUE;
  560.     }
  561.     else if ((IGGlblTransPrefPos == NULL || strlen(IGGlblViewPrefPos) == 0) &&
  562.          TransGeometry) {
  563.     i = XParseGeometry(TransGeometry, &TransPosX, &TransPosY,
  564.                                   &TransWidth, &TransHeight);
  565.     TransHasPos = i & XValue && i & YValue;
  566.     TransHasSize =  i & WidthValue && i & HeightValue;
  567.     }
  568.     else
  569.         TransHasSize = TransHasPos = FALSE;
  570.  
  571.     if (TransCursorColorStr != NULL &&
  572.     XParseColor(XDisplay, XColorMap, TransCursorColorStr, &Color) &&
  573.     XAllocColor(XDisplay, XColorMap, &Color)) {
  574.     TransCursorColor = (XColor *) IritMalloc(sizeof(XColor));
  575.     *TransCursorColor = Color;
  576.     }
  577.     else
  578.     TransCursorColor = NULL;
  579.  
  580.     if (ViewBackGroundColor &&
  581.     XParseColor(XDisplay, XColorMap, ViewBackGroundColor, &Color) &&
  582.     XAllocColor(XDisplay, XColorMap, &Color))
  583.     ViewBackGroundPixel = Color.pixel;
  584.     else
  585.     ViewBackGroundPixel = BlackPixel(XDisplay, XScreen);
  586.  
  587.     if (ViewBorderColor &&
  588.     XParseColor(XDisplay, XColorMap, ViewBorderColor, &Color) &&
  589.     XAllocColor(XDisplay, XColorMap, &Color))
  590.     ViewBorderPixel = Color.pixel;
  591.     else
  592.     ViewBorderPixel = WhitePixel(XDisplay, XScreen);
  593.  
  594.     if (ViewTextColor != NULL &&
  595.     XParseColor(XDisplay, XColorMap, ViewTextColor, &Color) &&
  596.     XAllocColor(XDisplay, XColorMap, &Color))
  597.     ViewTextPixel = Color.pixel;
  598.     else
  599.     ViewTextPixel = WhitePixel(XDisplay, XScreen);
  600.  
  601.     if (ViewBorderWidthStr)
  602.     ViewBorderWidth = atoi(ViewBorderWidthStr);
  603.     else
  604.     ViewBorderWidth = 1;
  605.  
  606.     if (IGGlblViewPrefPos &&
  607.     sscanf(IGGlblViewPrefPos, "%d,%d,%d,%d",
  608.            &ViewPosX, &ViewWidth, &ViewPosY, &ViewHeight) == 4) {
  609.     ViewWidth -= ViewPosX;
  610.     ViewHeight -= ViewPosY;
  611.     ViewHasSize = ViewHasPos = TRUE;
  612.     }
  613.     else if ((IGGlblViewPrefPos == NULL || strlen(IGGlblViewPrefPos) == 0) &&
  614.          ViewGeometry) {
  615.     i = XParseGeometry(ViewGeometry, &ViewPosX, &ViewPosY,
  616.                                  &ViewWidth, &ViewHeight);
  617.     ViewHasPos = i & XValue && i & YValue;
  618.     ViewHasSize = i & WidthValue && i & HeightValue;
  619.     }
  620.     else
  621.     ViewHasSize = ViewHasPos = FALSE;
  622.  
  623.     if (ViewCursorColorStr != NULL &&
  624.     XParseColor(XDisplay, XColorMap, ViewCursorColorStr, &Color) &&
  625.     XAllocColor(XDisplay, XColorMap, &Color)) {
  626.     ViewCursorColor = (XColor *) IritMalloc(sizeof(XColor));
  627.     *ViewCursorColor = Color;
  628.     }
  629.     else
  630.     ViewCursorColor = NULL;
  631.  
  632.     if (MaxColorsStr)
  633.     MaxColors = atoi(MaxColorsStr);
  634.     else
  635.     MaxColors = IG_MAX_COLOR;
  636.  
  637. }
  638.  
  639. /*****************************************************************************
  640. * Set up and draw a transformation window.                     *
  641. *****************************************************************************/
  642. static void SetTransformWindow(int argc, char **argv)
  643. {
  644.     int SubTransPosX, SubTransPosY, SubTransWidth, SubTransHeight;
  645.     long ValueMask;
  646.     XSizeHints Hints;
  647.     XSetWindowAttributes SetWinAttr;
  648.  
  649.     SetWinAttr.background_pixel = TransBackGroundPixel;
  650.     SetWinAttr.border_pixel = TransBorderPixel;
  651.     ValueMask = CWBackPixel | CWBorderPixel;
  652.  
  653.     Hints.flags = PMinSize | PMaxSize;
  654.     Hints.x = Hints.y = 1;
  655.     Hints.min_width = 100;
  656.     Hints.max_width = 1000;
  657.     Hints.min_height = 200;
  658.     Hints.max_height = 1000;
  659.     if (TransHasSize) {
  660.     Hints.flags |= PSize;
  661.     if (TransWidth < Hints.min_width)
  662.         TransWidth = Hints.min_width;
  663.     if (TransWidth > Hints.max_width)
  664.         TransWidth = Hints.max_width;
  665.     if (TransHeight < Hints.min_height)
  666.         TransHeight = Hints.min_height;
  667.     if (TransHeight > Hints.max_height)
  668.         TransHeight = Hints.max_height;
  669.     Hints.width = TransWidth;
  670.     Hints.height = TransHeight;
  671.     }
  672.     else {
  673.     Hints.flags |= PSize;
  674.     Hints.width = TransWidth = DEFAULT_TRANS_WIDTH;
  675.     Hints.height = TransHeight = DEFAULT_TRANS_HEIGHT;
  676.     }
  677.     if (TransHasPos) {
  678.     Hints.flags |= USPosition;
  679.     Hints.x = TransPosX;
  680.     Hints.y = TransPosY;
  681.     }
  682.  
  683.     TransformWndw = XCreateWindow(XDisplay, XRoot,
  684.                   TransPosX, TransPosY,
  685.                   TransWidth, TransHeight,
  686.                       1, 0, CopyFromParent, CopyFromParent,
  687.                       ValueMask, &SetWinAttr);
  688.  
  689.     XSetStandardProperties(XDisplay, TransformWndw,
  690.                RESOURCE_NAME, RESOURCE_NAME, None,
  691.                argv, argc,
  692.                &Hints);
  693.  
  694.     /* Set our own cursor: */
  695.     XCursor = XCreateFontCursor(XDisplay, XC_hand1);
  696.     XDefineCursor(XDisplay, TransformWndw, XCursor);
  697.     if (TransCursorColor != NULL)
  698.     XRecolorCursor(XDisplay, XCursor, TransCursorColor, &BlackColor);
  699.  
  700.     /* Now lets create the sub windows inside. Note we do not place them yet. */
  701.     SubTransPosX = 0;
  702.     SubTransPosY = TransHeight;
  703.     SubTransWidth = TransWidth - SubTransPosX * 2;
  704.     SubTransHeight = TransHeight / 25;
  705.  
  706.     /* OBJECT/SCREEN space toggle: */
  707.     ObjScrTglWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  708.                       SubTransWidth, SubTransHeight);
  709.  
  710.     /* PERSPECTIVE/ORTHOGRPHIC toggle: */
  711.     PersOrthoTglWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  712.                          SubTransWidth, SubTransHeight);
  713.     PersOrthoZWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  714.                          SubTransWidth, SubTransHeight);
  715.  
  716.     /* ROTATE: */
  717.     RotateXWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  718.                     SubTransWidth, SubTransHeight);
  719.     RotateYWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  720.                     SubTransWidth, SubTransHeight);
  721.     RotateZWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  722.                     SubTransWidth, SubTransHeight);
  723.     /* TRANSLATE: */
  724.     TranslateXWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  725.                        SubTransWidth, SubTransHeight);
  726.     TranslateYWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  727.                        SubTransWidth, SubTransHeight);
  728.     TranslateZWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  729.                        SubTransWidth, SubTransHeight);
  730.     /* SCALE: */
  731.     ScaleWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  732.                       SubTransWidth, SubTransHeight);
  733.  
  734.     /* DEPTH CUE: */
  735.     DepthCueWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  736.                      SubTransWidth, SubTransHeight);
  737.  
  738.     /* SAVE MATRIX: */
  739.     SaveMatrixWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  740.                        SubTransWidth, SubTransHeight);
  741.  
  742.     /* PUSH MATRIX: */
  743.     PushMatrixWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  744.                        SubTransWidth, SubTransHeight);
  745.  
  746.     /* POP MATRIX: */
  747.     PopMatrixWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  748.                       SubTransWidth, SubTransHeight);
  749.  
  750.     /* QUIT: */
  751.     QuitWndw = SetTransformSubWindow(SubTransPosX, SubTransPosY,
  752.                      SubTransWidth, SubTransHeight);
  753.  
  754.     XSelectInput(XDisplay, TransformWndw, ExposureMask);
  755. }
  756.  
  757. /*****************************************************************************
  758. * Redraw a transformation window (after exposure or resize events).         *
  759. *****************************************************************************/
  760. static void RedrawTransformWindow(void)
  761. {
  762.     int SubTransPosX, SubTransPosY,
  763.         SizeChanged = FALSE;
  764.     unsigned long SubTransWidth, SubTransHeight;
  765.     long ValueMask;
  766.     XSizeHints Hints;
  767.     XWindowAttributes TransWindowAttr;
  768.     XSetWindowAttributes SetWinAttr;
  769.  
  770.     XClearWindow(XDisplay, TransformWndw);
  771.  
  772.     /* Get the window attributes, and see if it is the same size or not. */
  773.     XGetWindowAttributes(XDisplay, TransformWndw, &TransWindowAttr);
  774.     if (TransWindowAttr.width != TransWidth ||
  775.     TransWindowAttr.height != TransHeight) {
  776.     SizeChanged = TRUE;
  777.     TransWidth = TransWindowAttr.width;
  778.     TransHeight = TransWindowAttr.height;
  779.     }
  780.  
  781.     /* Now lets update the sub windows inside: */
  782.     SubTransPosX = MIN(TransWidth / 10, 20);
  783.     SubTransPosY =  TransHeight / 28;
  784.     SubTransWidth = TransWidth - SubTransPosX * 2;
  785.     SubTransHeight = TransHeight / 28;
  786.  
  787.     /* OBJECT/SCREEN space toggle: */
  788.     RedrawTransformSubWindow(ObjScrTglWndw, SubTransPosX, SubTransPosY,
  789.                  SubTransWidth, SubTransHeight, FALSE,
  790.                  IGGlblTransformMode == IG_TRANS_OBJECT ?
  791.                  "Object" : "Screen");
  792.     SubTransPosY += SubTransHeight * 2;
  793.  
  794.     /* PERSPECTIVE/ORTHOGRAPHIC toggle: */
  795.     RedrawTransformSubWindow(PersOrthoTglWndw, SubTransPosX, SubTransPosY,
  796.                  SubTransWidth, SubTransHeight, FALSE,
  797.                  IGGlblViewMode == IG_VIEW_ORTHOGRAPHIC ?
  798.                  "Orthographic" : "Perspective");
  799.     SubTransPosY += SubTransHeight;
  800.     RedrawTransformSubWindow(PersOrthoZWndw, SubTransPosX, SubTransPosY,
  801.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  802.     SubTransPosY += SubTransHeight;
  803.     DrawText(TransformWndw, "Z", SubTransPosX / 2,
  804.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  805.     SubTransPosY += SubTransHeight;
  806.  
  807.     /* ROTATE: */
  808.     DrawText(TransformWndw, "Rotate", TransWidth / 2, SubTransPosY,
  809.          TransTextPixel);
  810.     SubTransPosY += SubTransHeight / 2;
  811.     RedrawTransformSubWindow(RotateXWndw, SubTransPosX, SubTransPosY,
  812.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  813.     SubTransPosY += SubTransHeight;
  814.     DrawText(TransformWndw, "X", SubTransPosX / 2,
  815.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  816.     RedrawTransformSubWindow(RotateYWndw, SubTransPosX, SubTransPosY,
  817.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  818.     SubTransPosY += SubTransHeight;
  819.     DrawText(TransformWndw, "Y", SubTransPosX / 2,
  820.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  821.     RedrawTransformSubWindow(RotateZWndw, SubTransPosX, SubTransPosY,
  822.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  823.     SubTransPosY += SubTransHeight;
  824.     DrawText(TransformWndw, "Z", SubTransPosX / 2,
  825.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  826.  
  827.     /* TRANSLATE: */
  828.     SubTransPosY += SubTransHeight;
  829.     DrawText(TransformWndw, "Translate", TransWidth / 2, SubTransPosY,
  830.          TransTextPixel);
  831.     SubTransPosY += SubTransHeight / 2;
  832.     RedrawTransformSubWindow(TranslateXWndw, SubTransPosX, SubTransPosY,
  833.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  834.     SubTransPosY += SubTransHeight;
  835.     DrawText(TransformWndw, "X", SubTransPosX / 2,
  836.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  837.     RedrawTransformSubWindow(TranslateYWndw, SubTransPosX, SubTransPosY,
  838.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  839.     SubTransPosY += SubTransHeight;
  840.     DrawText(TransformWndw, "Y", SubTransPosX / 2,
  841.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  842.     RedrawTransformSubWindow(TranslateZWndw, SubTransPosX, SubTransPosY,
  843.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  844.     SubTransPosY += SubTransHeight;
  845.     DrawText(TransformWndw, "Z", SubTransPosX / 2,
  846.          SubTransPosY - SubTransHeight / 4, TransTextPixel);
  847.  
  848.     /* SCALE: */
  849.     SubTransPosY += SubTransHeight;
  850.     DrawText(TransformWndw, "Scale", TransWidth / 2, SubTransPosY,
  851.          TransTextPixel);
  852.     SubTransPosY += SubTransHeight / 2;
  853.     RedrawTransformSubWindow(ScaleWndw, SubTransPosX, SubTransPosY,
  854.                  SubTransWidth, SubTransHeight, TRUE, NULL);
  855.  
  856.     /* DEPTH CUE: */
  857.     SubTransPosY += SubTransHeight * 2;
  858.     RedrawTransformSubWindow(DepthCueWndw, SubTransPosX, SubTransPosY,
  859.                  SubTransWidth, SubTransHeight, FALSE,
  860.                  IGGlblDepthCue ? "Depth Cue" : "No Depth Cue");
  861.  
  862.     /* SAVE MATRIX: */
  863.     SubTransPosY += SubTransHeight * 2;
  864.     RedrawTransformSubWindow(SaveMatrixWndw, SubTransPosX, SubTransPosY,
  865.                  SubTransWidth, SubTransHeight, FALSE,
  866.                  "Save Matrix");
  867.  
  868.     /* PUSH MATRIX: */
  869.     SubTransPosY += SubTransHeight + SubTransHeight / 2;
  870.     RedrawTransformSubWindow(PushMatrixWndw, SubTransPosX, SubTransPosY,
  871.                  SubTransWidth, SubTransHeight, FALSE,
  872.                  "Push Matrix");
  873.  
  874.     /* POP MATRIX: */
  875.     SubTransPosY += SubTransHeight + SubTransHeight / 2;
  876.     RedrawTransformSubWindow(PopMatrixWndw, SubTransPosX, SubTransPosY,
  877.                  SubTransWidth, SubTransHeight, FALSE,
  878.                  "Pop Matrix");
  879.  
  880.     /* QUIT: */
  881.     SubTransPosY += SubTransHeight * 3;
  882.     RedrawTransformSubWindow(QuitWndw, SubTransPosX, SubTransPosY,
  883.                  SubTransWidth, SubTransHeight, FALSE, "Quit" );
  884.  
  885.     /* Save half of the window width so we can refer to the zero point on X */
  886.     /* axes, which is the vertical line in the middle of the window:        */
  887.     SubWindowWidthState2 = SubTransWidth / 2;
  888.     SubWindowHeightState2 = SubTransHeight / 2;
  889.  
  890.     GraphicFlush();
  891. }
  892.  
  893. /*****************************************************************************
  894. * Set up a transformation sub window.                         *
  895. *****************************************************************************/
  896. static Window SetTransformSubWindow(int SubTransPosX, int SubTransPosY,
  897.             unsigned int SubTransWidth, unsigned int SubTransHeight)
  898. {
  899.     long ValueMask;
  900.     XSetWindowAttributes SetWinAttr;
  901.     Window Win;
  902.  
  903.     SetWinAttr.background_pixel = TransSubWinBackPixel;
  904.     SetWinAttr.border_pixel = TransSubWinBorderPixel;
  905.     SetWinAttr.bit_gravity = SetWinAttr.win_gravity = CenterGravity;
  906.     ValueMask = CWBackPixel | CWBorderPixel | CWBitGravity | CWWinGravity;
  907.  
  908.     Win = XCreateWindow(XDisplay, TransformWndw,
  909.             SubTransPosX, SubTransPosY,
  910.             SubTransWidth, SubTransHeight,
  911.             1, 0, CopyFromParent, CopyFromParent,
  912.             ValueMask, &SetWinAttr);
  913.  
  914.     XSelectInput(XDisplay, Win, ButtonPressMask | Button1MotionMask);
  915.  
  916.     XMapWindow(XDisplay, Win);
  917.  
  918.     return Win;
  919. }
  920.  
  921. /*****************************************************************************
  922. * Redraw a transformation sub window.                         *
  923. *****************************************************************************/
  924. static void RedrawTransformSubWindow(Window Win,
  925.     int SubTransPosX, int SubTransPosY,
  926.     unsigned int SubTransWidth, unsigned int SubTransHeight,
  927.     int DrawMiddleVertLine, char *DrawString)
  928. {
  929.     XGCValues values;
  930.  
  931.     XMoveResizeWindow(XDisplay, Win, SubTransPosX, SubTransPosY,
  932.                                        SubTransWidth, SubTransHeight);
  933.     if (DrawMiddleVertLine) {
  934.     values.foreground = TransSubWinBorderPixel;
  935.     XChangeGC(XDisplay, XTransGraphContext, GCForeground, &values);
  936.  
  937.     XDrawLine(XDisplay, Win, XTransGraphContext,
  938.           SubTransWidth / 2, 0, SubTransWidth / 2, SubTransHeight);
  939.     }
  940.     if (DrawString != NULL) {
  941.     DrawText(Win, DrawString, SubTransWidth / 2, SubTransHeight / 2,
  942.          TransTextPixel);
  943.     }
  944. }
  945.  
  946. /*****************************************************************************
  947. * Set up a view window.                                 *
  948. *****************************************************************************/
  949. static void SetViewWindow(int argc, char **argv)
  950. {
  951.     long ValueMask;
  952.     XSizeHints Hints;
  953.     XSetWindowAttributes SetWinAttr;
  954.  
  955.     SetWinAttr.background_pixel = ViewBackGroundPixel;
  956.     SetWinAttr.border_pixel = ViewBorderPixel;
  957.     ValueMask = CWBackPixel | CWBorderPixel;
  958.  
  959.     Hints.flags = PMinSize | PMaxSize;
  960.     Hints.x = Hints.y = 1;
  961.     Hints.min_width = 50;
  962.     Hints.max_width = 1000;
  963.     Hints.min_height = 50;
  964.     Hints.max_height = 1000;
  965.     if (ViewHasSize) {
  966.     Hints.flags |= PSize;
  967.     if (ViewWidth < Hints.min_width)
  968.         ViewWidth = Hints.min_width;
  969.     if (ViewWidth > Hints.max_width)
  970.         ViewWidth = Hints.max_width;
  971.     if (ViewHeight < Hints.min_height)
  972.         ViewHeight = Hints.min_height;
  973.     if (ViewHeight > Hints.max_height)
  974.         ViewHeight = Hints.max_height;
  975.     Hints.width = ViewWidth;
  976.     Hints.height = ViewHeight;
  977.     }
  978.     else {
  979.     Hints.flags |= PSize;
  980.     Hints.width = ViewWidth = DEFAULT_VIEW_WIDTH;
  981.     Hints.height = ViewHeight = DEFAULT_VIEW_HEIGHT;
  982.     }
  983.     if (ViewHasPos) {
  984.     Hints.flags |= USPosition;
  985.     Hints.x = ViewPosX;
  986.     Hints.y = ViewPosY;
  987.     }
  988.  
  989.     ViewWndw = XCreateWindow(XDisplay, XRoot,
  990.                  ViewPosX, ViewPosY,
  991.                  ViewWidth, ViewHeight,
  992.                  1, 0, CopyFromParent, CopyFromParent,
  993.                  ValueMask, &SetWinAttr);
  994.  
  995.     XSetStandardProperties(XDisplay, ViewWndw,
  996.                RESOURCE_NAME, RESOURCE_NAME, None,
  997.                argv, argc,
  998.                &Hints);
  999.  
  1000.     /* Set our own cursor: */
  1001.     XCursor = XCreateFontCursor(XDisplay, XC_arrow);
  1002.     XDefineCursor(XDisplay, ViewWndw, XCursor);
  1003.     if (ViewCursorColor != NULL)
  1004.     XRecolorCursor(XDisplay, XCursor, ViewCursorColor, &BlackColor);
  1005.  
  1006.     XSelectInput(XDisplay, ViewWndw,
  1007.          ExposureMask | ButtonPressMask | ButtonReleaseMask | ButtonMotionMask);
  1008.     
  1009.     XMapWindow(XDisplay, ViewWndw);
  1010. }
  1011.  
  1012. /*****************************************************************************
  1013. * Redraw the view window.                             *
  1014. *****************************************************************************/
  1015. void IGRedrawViewWindow(void)
  1016. {
  1017.     IPObjectStruct *PObj;
  1018.  
  1019.     XClearWindow(XDisplay, ViewWndw);
  1020.  
  1021.     switch (IGGlblViewMode) {         /* Update the current view. */
  1022.     case IG_VIEW_ORTHOGRAPHIC:
  1023.         GEN_COPY(IGGlblCrntViewMat, IritPrsrViewMat, sizeof(MatrixType));
  1024.         break;
  1025.     case IG_VIEW_PERSPECTIVE:
  1026.         MatMultTwo4by4(IGGlblCrntViewMat, IritPrsrViewMat,
  1027.                             IritPrsrPrspMat);
  1028.         break;
  1029.     }
  1030.  
  1031.     for (PObj = IGGlblDisplayList; PObj != NULL; PObj = PObj -> Pnext)
  1032.     IGDrawObject(PObj);
  1033. }
  1034.  
  1035. /******************************************************************************
  1036. * Flush output of graphic command.                          *
  1037. ******************************************************************************/
  1038. static void GraphicFlush(void)
  1039. {
  1040.     XFlush(XDisplay);
  1041. }
  1042.  
  1043. /******************************************************************************
  1044. * Handle X events                                  *
  1045. ******************************************************************************/
  1046. static IGGraphicEventType GetGraphicEvent(XtAppContext App,
  1047.                       RealType *ChangeFactor)
  1048. {
  1049.     static int LastX,
  1050.     ButtonPressedViewWndw = FALSE;
  1051.     static CagdPtStruct
  1052.     *PtList = NULL,
  1053.     *PtListTail = NULL;
  1054.     int Dx;
  1055.     XEvent Event;
  1056.     XWindowAttributes WinAttr;
  1057.  
  1058.     XMapWindow(XDisplay, TransformWndw);
  1059.  
  1060.     while (TRUE) {
  1061.     /* Maybe we have something in communication socket. */
  1062.     if (!IGGlblStandAlone &&
  1063.         IGReadObjectsFromSocket(IGGlblViewMode, &IGGlblDisplayList))
  1064.         IGRedrawViewWindow();
  1065.  
  1066.     if (XtAppPending(App)) {
  1067.         XtAppNextEvent(App, &Event);
  1068.  
  1069.         XtDispatchEvent(&Event);
  1070.     }
  1071.  
  1072.     if (XPending(XDisplay)) {
  1073.         XNextEvent(XDisplay, &Event);
  1074.  
  1075.         switch (Event.type) {
  1076.         case Expose:
  1077.                 /* Get rid of all Expose events in the queue. */
  1078.                 while (XCheckWindowEvent(XDisplay, Event.xbutton.window,
  1079.                          ExposureMask, &Event));
  1080.             if (Event.xbutton.window == TransformWndw)
  1081.             RedrawTransformWindow();
  1082.             else if (Event.xbutton.window == ViewWndw) {
  1083.             XGetWindowAttributes(XDisplay, ViewWndw, &WinAttr);
  1084.             ViewWidth = WinAttr.width;
  1085.             ViewHeight = WinAttr.height;
  1086.             IGRedrawViewWindow();
  1087.             }
  1088.             break;
  1089.         case ButtonRelease:
  1090.             if (Event.xbutton.window == ViewWndw) {
  1091.             ButtonPressedViewWndw = FALSE;
  1092. /*
  1093. {
  1094.     static int FCount = 1;
  1095.     int i;
  1096.     char Name[80];
  1097.     CagdPtStruct *Pt;
  1098.     FILE *f;
  1099.  
  1100.     for (i = 0, Pt = PtList; Pt != NULL; Pt = Pt -> Pnext, i++);
  1101.     sprintf(Name, "mouse%d.dat", FCount++);
  1102.     f = fopen(Name, "w");
  1103.     fprintf(f, "[OBJECT MOUSE%dINPUT\n    [POINTLIST %d\n", FCount++, i);
  1104.     for (Pt = PtList; Pt != NULL; Pt = Pt -> Pnext)
  1105.     fprintf(f, "\t[%lf %lf %lf]\n", Pt -> Pt[0], Pt -> Pt[1], Pt -> Pt[2]);
  1106.     fprintf(f, "    ]\n]\n");
  1107.     fclose(f);
  1108. }
  1109. */
  1110.             if (PtList != NULL) {
  1111.                 int Len = CagdListLength(PtList);
  1112.                 CagdCrvStruct
  1113.                 *Crv = BspCrvInterpPts(PtList, 3, MIN(50, Len),
  1114.                                CAGD_CHORD_LEN_PARAM);
  1115.                 IPObjectStruct
  1116.                     *PObj = GenCRVObject(Crv);
  1117.  
  1118.                 CagdPtFreeList(PtList);
  1119.                 PtList = PtListTail = NULL;
  1120.  
  1121. CagdDbg(Crv);
  1122. {
  1123.     static int FCount = 1;
  1124.     int i;
  1125.     char Name[80];
  1126.     CagdPtStruct *Pt;
  1127.     FILE *f;
  1128.  
  1129.     for (i = 0, Pt = PtList; Pt != NULL; Pt = Pt -> Pnext, i++);
  1130.     sprintf(Name, "cmouse%d.dat", FCount++);
  1131.     f = fopen(Name, "w");
  1132.     IritPrsrPutObjectToFile(f, PObj);
  1133.     fclose(f);
  1134. }
  1135.                 PObj -> Pnext = IGGlblDisplayList;
  1136.                 IGGlblDisplayList = PObj;
  1137.             }
  1138.             }
  1139.             break;
  1140.         case ButtonPress:
  1141.             if (Event.xbutton.window == ViewWndw) {
  1142.             ButtonPressedViewWndw = TRUE;
  1143.             break;
  1144.             }
  1145.  
  1146.             LastX = Event.xbutton.x;
  1147.             *ChangeFactor =
  1148.             ((RealType) (LastX - SubWindowWidthState2)) /
  1149.                          SubWindowWidthState2;
  1150.             if (Event.xbutton.window == ObjScrTglWndw) {
  1151.             XClearWindow(XDisplay, ObjScrTglWndw);
  1152.             IGGlblTransformMode =
  1153.                 IGGlblTransformMode == IG_TRANS_OBJECT ?
  1154.                            IG_TRANS_SCREEN :
  1155.                            IG_TRANS_OBJECT;
  1156.             DrawText(ObjScrTglWndw,
  1157.                 IGGlblTransformMode == IG_TRANS_OBJECT ? "Object" :
  1158.                                      "Screen",
  1159.                 SubWindowWidthState2, SubWindowHeightState2,
  1160.                 TransTextPixel);
  1161.             return IG_EVENT_SCR_OBJ_TGL;
  1162.             }
  1163.             else if (Event.xbutton.window == PersOrthoTglWndw) {
  1164.             XClearWindow(XDisplay, PersOrthoTglWndw);
  1165.             IGGlblViewMode =
  1166.                 IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  1167.                           IG_VIEW_ORTHOGRAPHIC :
  1168.                           IG_VIEW_PERSPECTIVE;
  1169.             DrawText(PersOrthoTglWndw,
  1170.                  IGGlblViewMode == IG_VIEW_PERSPECTIVE ?
  1171.                      "Perspective" : "Orthographic",
  1172.                  SubWindowWidthState2, SubWindowHeightState2,
  1173.                  TransTextPixel);
  1174.             return IG_EVENT_PERS_ORTHO_TGL;
  1175.             }
  1176.             else if (Event.xbutton.window == PersOrthoZWndw) {
  1177.             return IG_EVENT_PERS_ORTHO_Z;
  1178.             }
  1179.             else if (Event.xbutton.window == RotateXWndw) {
  1180.             return IG_EVENT_ROTATE_X;
  1181.             }
  1182.             else if (Event.xbutton.window == RotateYWndw) {
  1183.             return IG_EVENT_ROTATE_Y;
  1184.             }
  1185.             else if (Event.xbutton.window == RotateZWndw) {
  1186.             return IG_EVENT_ROTATE_Z;
  1187.             }
  1188.             else if (Event.xbutton.window == TranslateXWndw) {
  1189.             return IG_EVENT_TRANSLATE_X;
  1190.             }
  1191.             else if (Event.xbutton.window == TranslateYWndw) {
  1192.             return IG_EVENT_TRANSLATE_Y;
  1193.             }
  1194.             else if (Event.xbutton.window == TranslateZWndw) {
  1195.             return IG_EVENT_TRANSLATE_Z;
  1196.             }
  1197.             else if (Event.xbutton.window == ScaleWndw) {
  1198.             return IG_EVENT_SCALE;
  1199.             }
  1200.             else if (Event.xbutton.window == DepthCueWndw) {
  1201.             XClearWindow(XDisplay, DepthCueWndw);
  1202.             IGGlblDepthCue = !IGGlblDepthCue;
  1203.             DrawText(DepthCueWndw,
  1204.                  IGGlblDepthCue ? "Depth Cue" : "No Depth Cue",
  1205.                  SubWindowWidthState2, SubWindowHeightState2,
  1206.                  TransTextPixel);
  1207.             return IG_EVENT_DEPTH_CUE;
  1208.             }
  1209.             else if (Event.xbutton.window == SaveMatrixWndw) {
  1210.             return IG_EVENT_SAVE_MATRIX;
  1211.             }
  1212.             else if (Event.xbutton.window == PushMatrixWndw) {
  1213.             return IG_EVENT_PUSH_MATRIX;
  1214.             }
  1215.             else if (Event.xbutton.window == PopMatrixWndw) {
  1216.             return IG_EVENT_POP_MATRIX;
  1217.             }
  1218.             else if (Event.xbutton.window == QuitWndw) {
  1219.             GraphicFlush();
  1220.             return IG_EVENT_QUIT;
  1221.             }
  1222.             break;
  1223.         case MotionNotify:
  1224.             if (Event.xbutton.window == ViewWndw) {
  1225.             CagdPtStruct
  1226.                 *NewPt = CagdPtNew();
  1227.  
  1228.             XDrawPoint(XDisplay, ViewWndw, XViewGraphContext,
  1229.                    Event.xbutton.x, Event.xbutton.y);
  1230.             GraphicFlush();
  1231.  
  1232.             /* Save the point in a linked list. */
  1233.             NewPt -> Pt[0] = X11_INVMAP_X_COORD(Event.xbutton.x);
  1234.             NewPt -> Pt[1] = X11_INVMAP_Y_COORD(Event.xbutton.y);
  1235.             NewPt -> Pt[2] = 0.0;
  1236.  
  1237.             if (PtList == NULL)
  1238.                 PtList = PtListTail = NewPt;
  1239.             else {
  1240.                 PtListTail -> Pnext = NewPt;
  1241.                 PtListTail = NewPt;
  1242.             }
  1243.             break;
  1244.             }
  1245.  
  1246.             /* We may get events of movement in Y which are ignored. */
  1247.             if (Event.xbutton.x - LastX == 0)
  1248.             break;
  1249.  
  1250.             *ChangeFactor = ((RealType) (Event.xbutton.x - LastX)) /
  1251.                             SubWindowWidthState2;
  1252.             LastX = Event.xbutton.x;
  1253.  
  1254.             if (Event.xbutton.window == PersOrthoZWndw) {
  1255.             return IG_EVENT_PERS_ORTHO_Z;
  1256.             }
  1257.             else if (Event.xbutton.window == RotateXWndw) {
  1258.             return IG_EVENT_ROTATE_X;
  1259.             }
  1260.             else if (Event.xbutton.window == RotateYWndw) {
  1261.             return IG_EVENT_ROTATE_Y;
  1262.             }
  1263.             else if (Event.xbutton.window == RotateZWndw) {
  1264.             return IG_EVENT_ROTATE_Z;
  1265.             }
  1266.             else if (Event.xbutton.window == TranslateXWndw) {
  1267.             return IG_EVENT_TRANSLATE_X;
  1268.             }
  1269.             else if (Event.xbutton.window == TranslateYWndw) {
  1270.             return IG_EVENT_TRANSLATE_Y;
  1271.             }
  1272.             else if (Event.xbutton.window == TranslateZWndw) {
  1273.             return IG_EVENT_TRANSLATE_Z;
  1274.             }
  1275.             else if (Event.xbutton.window == ScaleWndw) {
  1276.             return IG_EVENT_SCALE;
  1277.             }
  1278.             break;
  1279.         default:
  1280.             fprintf(stderr,
  1281.                 "x11drvs: undefined event type %d.\n", Event.type);
  1282.             break;
  1283.         }
  1284.     }
  1285.     IritSleep(10);
  1286.     }
  1287. }
  1288.  
  1289. /******************************************************************************
  1290. * Handle the event of a pop up window.                          *
  1291. ******************************************************************************/
  1292. int IGHandleState(int State, int Refresh)
  1293. {
  1294.     int UpdateView = TRUE;
  1295.     XGCValues values;
  1296.  
  1297.     switch (State) {
  1298.     case IG_STATE_DEPTH_CUE:
  1299.         XClearWindow(XDisplay, DepthCueWndw);
  1300.         IGGlblDepthCue = !IGGlblDepthCue;
  1301.         DrawText(DepthCueWndw,
  1302.              IGGlblDepthCue ? "Depth Cue" : "No Depth Cue",
  1303.              SubWindowWidthState2, SubWindowHeightState2,
  1304.              TransTextPixel);
  1305.  
  1306.         break;
  1307.     case IG_STATE_DOUBLE_BUFFER:
  1308.         IGGlblDoDoubleBuffer = !IGGlblDoDoubleBuffer;
  1309.         break;
  1310.     case IG_STATE_WIDER_LINES:
  1311.         IGGlblLineWidth *= 2;
  1312.         values.line_width = IGGlblLineWidth;
  1313.         XChangeGC(XDisplay, XViewGraphContext, GCLineWidth, &values);
  1314.         break;
  1315.     case IG_STATE_NARROW_LINES:
  1316.         IGGlblLineWidth /= 2;
  1317.         if (IGGlblLineWidth < 1)
  1318.         IGGlblLineWidth = 1;
  1319.         values.line_width = IGGlblLineWidth;
  1320.         XChangeGC(XDisplay, XViewGraphContext, GCLineWidth, &values);
  1321.         break;
  1322.     default:
  1323.         UpdateView = IGDefaultStateHandler(State, Refresh);
  1324.         break;
  1325.     }
  1326.  
  1327.     IGCreateStateMenu();
  1328.  
  1329.     return UpdateView;
  1330. }
  1331.  
  1332. /******************************************************************************
  1333. * Draw text centered at the given position.                      *
  1334. ******************************************************************************/
  1335. static void DrawText(Window Win, char *Str, int PosX, int PosY,
  1336.              unsigned long Color)
  1337. {
  1338.     int Len = strlen(Str),
  1339.         Width = XTextWidth(XLoadedFont, Str, Len);
  1340.     XGCValues values;
  1341.  
  1342.     values.foreground = Color;
  1343.     XChangeGC(XDisplay, XTransGraphContext, GCForeground, &values);
  1344.  
  1345.     XDrawString(XDisplay, Win, XTransGraphContext, PosX - Width / 2,
  1346.         PosY + XFontYOffsetToCenter, Str, Len);
  1347. }
  1348.  
  1349. /*****************************************************************************
  1350. * Routine to make some sound.                             *
  1351. *****************************************************************************/
  1352. void IGIritBeep(void)
  1353. {
  1354.     XBell(XDisplay, 0);
  1355. }
  1356.  
  1357. /*****************************************************************************
  1358. * Scales callbacks of commands of mouse buttons.                 *
  1359. *****************************************************************************/
  1360. static void ScalesCB(Widget w, IGGraphicEventType EventType)
  1361. {
  1362.     int NewValue;
  1363.     char buf[10];
  1364.     RealType ChangeFactor[2];
  1365.  
  1366.     XmScaleGetValue(w, &NewValue);
  1367. fprintf(stderr, "ScalesCB = %d\n", NewValue);
  1368.     XmScaleSetValue(w, 0);
  1369.  
  1370.  
  1371.     ChangeFactor[0] = IGGlblChangeFactor * (NewValue - OldValue) / 100;
  1372.     ChangeFactor[1] = 0.0;
  1373.     if (IGProcessEvent(EventType, ChangeFactor))
  1374.         IGRedrawViewWindow(); 
  1375.     OldValue = 0;
  1376. }
  1377.  
  1378. /*****************************************************************************
  1379. * Scales drag movements.                             *
  1380. *****************************************************************************/
  1381. static void DragCB(Widget w, IGGraphicEventType EventType)
  1382. {
  1383.     int NewValue;
  1384.     RealType ChangeFactor[2];
  1385.  
  1386.     XmScaleGetValue(w, &NewValue);
  1387. fprintf(stderr, "DragCB = %d\n", NewValue);
  1388.     ChangeFactor[0] = IGGlblChangeFactor * (NewValue - OldValue) / 100;
  1389.     ChangeFactor[1] = 0.0;
  1390.     if (IGProcessEvent(EventType, ChangeFactor))
  1391.     IGRedrawViewWindow();
  1392.     OldValue = NewValue;
  1393. }
  1394.  
  1395. /*****************************************************************************
  1396. * Handle transformation window buttons.                         *
  1397. *****************************************************************************/
  1398. static void TransformCB(Widget w, int State)
  1399. {
  1400.     RealType ChangeFactor[2];
  1401.  
  1402.     switch(State) {
  1403.     case IG_EVENT_QUIT:
  1404.         exit(0);
  1405.  
  1406.     default:
  1407.         ChangeFactor[0] = ChangeFactor[1] = 1.0;
  1408.         if (IGProcessEvent(State, ChangeFactor)) 
  1409.         IGRedrawViewWindow();
  1410.     }
  1411. }        
  1412.  
  1413. /*****************************************************************************
  1414. * DESCRIPTION:                                                               M
  1415. *   Should we stop this animation. Senses the event queue of X11.            M
  1416. *                                                                            *
  1417. * PARAMETERS:                                                                M
  1418. *   Anim:     The animation to abort.                                        M
  1419. *                                                                            *
  1420. * RETURN VALUE:                                                              M
  1421. *   int:      TRUE if we need to abort, FALSE otherwise.                     M
  1422. *                                                                            *
  1423. * KEYWORDS:                                                                  M
  1424. *   AnimCheckInterrupt                                                       M
  1425. *****************************************************************************/
  1426. int AnimCheckInterrupt(AnimationStruct *Anim)
  1427. {
  1428.     if (XPending(XDisplay)) {
  1429.     Anim -> StopAnim = TRUE;
  1430.     fprintf(stderr, "\nAnimation was interrupted by the user.\n");
  1431.     return TRUE;
  1432.     }
  1433.     else
  1434.         return FALSE;
  1435. }
  1436.